/**
 * @Title: [DomainUtil.java]
 * @Package: [com.yixun.qfbao.utils]
 * @author: [shaoping.jiao]
 * @CreateDate: [2017年11月10日 下午2:40:01]
 * @UpdateUser: [shaoping.jiao]
 * @UpdateDate: [2017年11月10日 下午2:40:01]
 * @Description: [DomainInterceptor]
 * @version: [V1.0]
 */
package com.yixun.qfbao.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.yixun.qfbao.apidto.base.CommonReqDTO;
import com.yixun.qfbao.constants.ApiConstant;
import com.yixun.qfbao.dto.base.BaseRequestDTO;
import com.yixun.qfbao.model.PartnerInfo;
import com.yixun.qfbao.model.enums.SystemIdEnum;
import com.yixun.qfbao.util.RedisUtil;
import com.yixun.qfbao.utils.LoginUtils;

/**
 * @ClassName: DomainUtil
 * @author: [shaoping.jiao]
 * @CreateDate: [2017年11月10日 下午2:40:01]
 * @UpdateUser: [shaoping.jiao]
 * @UpdateDate: [2017年11月10日 下午2:40:01]
 * @Description: [DomainInterceptor]
 * @version: [V1.0]
 */
@Component
@Aspect
public class DomainInterceptor {

    @Autowired
    private LoginUtils loginUtils;

    // 第一个*号：表示返回类型，*号表示所有的类型
    // 包名：表示需要拦截的包名，后面的两个句点表示当前包和当前包的所有子包
    // 第二个*号：表示类名，*号表示所有的类
    // *(..):最后这个星号表示方法名，*号表示所有的方法，后面括弧里面表示方法的参数，两个句点表示任何参数。
    @Pointcut("execution(* com.yixun.qfbao.controller..*.*(..,javax.servlet.http.HttpServletRequest,..))  && @annotation(com.yixun.qfbao.annotations.Domain)")
    public void pointcut() {
    }

    // 环绕通知
    @Around("pointcut()")
    public Object updateDomain(ProceedingJoinPoint pjp) throws Throwable {

        HttpServletRequest request = null;
        BaseRequestDTO baseRequestDTO = null;
        int i = 0;
        int reqVoIndex = 0;
        for (int j = 0; j < pjp.getArgs().length; j++) {
            if (pjp.getArgs()[j] instanceof HttpServletRequest) {
                request = (HttpServletRequest) pjp.getArgs()[j];
                i = j;
            }
            if (pjp.getArgs()[j] instanceof BaseRequestDTO) {
                baseRequestDTO = (BaseRequestDTO) pjp.getArgs()[j];
                reqVoIndex = j;
            }
        }
        if (null == request) {
            return pjp.proceed();
        }
        String loginType = request.getHeader(ApiConstant.LOGINTYPE);
        // 从APP端登录不截取domain
        if (SystemIdEnum.APP_ASSISTANT.getCode().equals(loginType) || SystemIdEnum.APP_AGENCY.getCode().equals(loginType)) {
            String userIdStr = request.getHeader("userId");
            if (StringUtils.isEmpty(userIdStr)) {
                userIdStr = request.getParameter("params.userId");
            }
            if (StringUtils.isBlank(userIdStr)) {
                return pjp.proceed();
            }
            Long userId = Long.valueOf(userIdStr);
            PartnerInfo partnerInfo = loginUtils.getUser(userId);
            if (null == partnerInfo) {
                return pjp.proceed();
            }
            String domain = (String) loginUtils.get(ApiConstant.DOMAIN + partnerInfo.getId());
            Object[] args = pjp.getArgs();
            request.setAttribute(ApiConstant.DOMAIN, domain);
            args[i] = request;
            return pjp.proceed(args);
        } else if (SystemIdEnum.WEAPP_AGENCY.getCode().equals(loginType)) {//微信小程序
            String companyUuid = request.getHeader(ApiConstant.COMPANY_UUID);
            String wxOpenid = request.getHeader("wxOpenid");
            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            //如果redis中不存在
            if (StringUtils.isBlank(wxOpenid) || !RedisUtil.hasKey("wxOpenid:" + wxOpenid)) {
                response.sendError(401,"登录信息丢失");
                return null;
            }
            Object[] args = pjp.getArgs();
            if (baseRequestDTO.getParams() instanceof CommonReqDTO) {
                if (StringUtils.isNotEmpty(companyUuid)) {
                    ((CommonReqDTO) baseRequestDTO.getParams()).setCompanyUuid(companyUuid);
                    ((CommonReqDTO) baseRequestDTO.getParams()).setLoginType(loginType);
                }
            }
            args[reqVoIndex] = baseRequestDTO;
            return pjp.proceed(args);
        } else {
            String domain = request.getHeader(ApiConstant.ORIGIN);
            String companyUuid = request.getHeader(ApiConstant.COMPANY_UUID);
            String subDomain = "";
            if (StringUtils.isNotBlank(domain)){
                if(domain.indexOf(".") == -1) {
                    subDomain = domain.split(":")[1].split("//")[1];
                } else {
                    subDomain = domain.substring(domain.indexOf("//") + 2, domain.indexOf("."));
                }
            }
            Object[] args = pjp.getArgs();
            request.setAttribute(ApiConstant.DOMAIN, subDomain);
            request.setAttribute(ApiConstant.COMPANY_UUID, companyUuid);

            if (baseRequestDTO.getParams() instanceof CommonReqDTO) {
                if (StringUtils.isNotEmpty(companyUuid)) {
                    ((CommonReqDTO) baseRequestDTO.getParams()).setDomain(null);
                    ((CommonReqDTO) baseRequestDTO.getParams()).setCompanyUuid(companyUuid);
                } else {
                    ((CommonReqDTO) baseRequestDTO.getParams()).setCompanyUuid(null);
                    ((CommonReqDTO) baseRequestDTO.getParams()).setDomain(subDomain);
                }
            }
            args[i] = request;
            args[reqVoIndex] = baseRequestDTO;
            return pjp.proceed(args);
        }
    }
}

